package com.mapforge.selection;

import java.awt.Rectangle;
import java.util.Iterator;

/**
 * The {@link Selection} interface represents a set of selected points in
 * Cartesian coordinate space.
 * 
 * @author Will Morrison
 * 
 */
public interface Selection extends Cloneable, Iterable<ComparablePoint> {
	/**
	 * Returns the bounding rectangle of this selection.
	 * 
	 * The bounding rectangle is the smallest rectangle which can contain all
	 * the points in the selection.
	 * 
	 * @return bounding rectangle of the selection
	 */
	public Rectangle getBoundingRectangle();

	/**
	 * Determines whether the {@link Selection} contains points.
	 * 
	 * @return whether selection contains points
	 */
	public boolean isEmpty();

	/**
	 * Sets the origin of this selection to the specified point. All point's
	 * locations will be recalculated so they are relative to the specified
	 * origin.
	 * 
	 * 
	 */
	public void setOrigin(int x, int y);

	/**
	 * Returns an iterator which iterates over the selected points in this
	 * selection. Points returned by this iterator will be in row-major order.
	 * 
	 * @return iterator for this selection
	 */
	public Iterator<ComparablePoint> iterator();

	/**
	 * Returns an {@link Iterator} which iterators over points in this selection
	 * contained within the specified rectangle.
	 * 
	 * @param rectangle
	 *            specified rectangle
	 * @return iterator containing all points within specified rectangle
	 */
	public Iterator<ComparablePoint> iterator(Rectangle rectangle);

	/**
	 * Removes all points in this selection.
	 */
	public void clearSelection();

	/**
	 * Calculates the union of this selection against the specified selection.
	 * 
	 * @param other
	 *            specified selection with which to perform union
	 * @return whether this selection was altered due to this operation
	 */
	public boolean add(Selection other);

	/**
	 * Calculates the union of this selection and the specified selection, and
	 * returns the result. This operation will not alter this selection or the
	 * specified selection.
	 * 
	 * @param other
	 *            specified selection to perform union with
	 * @return result of this union
	 */
	public Selection addition(Selection other);

	/**
	 * Calculates the difference of this selection against the specified
	 * selection.
	 * 
	 * @param other
	 *            specified selection with which to perform subtraction
	 * @return whether this selection was altered due to this operation
	 */
	public boolean subtract(Selection other);

	/**
	 * Calculates the subtraction of this {@link Selection} from the specified
	 * {@link Selection} and returns the result. This operation will not alther
	 * this selection or the specified Selection.
	 * 
	 * @param other
	 *            specified {@link Selection}
	 * @return result of this operation
	 */
	public Selection subtraction(Selection other);

	/**
	 * Calculates the intersection of this selection against the specified
	 * collection.
	 * 
	 * @param other
	 *            specified selection with which to perform intersection
	 * @return whether this selection was altered due to this operation
	 */
	public boolean intersect(Selection other);

	public Selection intersection(Selection other);

	/**
	 * Determines whether any part of this selection is also within the
	 * specified selection.
	 * 
	 * @param other
	 *            specified selection
	 * @return whether this selection intersects the specified selection
	 */
	public boolean intersects(Selection other);

	/**
	 * Returns true if the specified x and y coordinates are contained within
	 * the bounds of this shape, or on the edge of this shape.
	 * 
	 * @param x
	 *            specified x coordinate
	 * @param y
	 *            specified y coordinate
	 * @return whether coordinates are in this selection
	 */
	public boolean contains(int x, int y);
}
